<template>
  <div class="fullpage-container" ref="container">
    <div
      class="fullpage-wrapper"
      :style="{ transform: `translateY(-${currentIndex * 100}vh)` }">
      <slot></slot>
    </div>

    <!-- 导航点 -->
    <div v-if="showDots" class="nav-dots">
      <div
        v-for="(item, index) in slides"
        :key="index"
        class="dot"
        :class="{ active: currentIndex === index }"
        @click="goToSlide(index)"></div>
    </div>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  ref,
  computed,
  onMounted,
  onUnmounted,
  watch,
} from "vue";
import logo from "@/assets/logo.png";
import logof from "@/assets/logo-f.png";

export default defineComponent({
  name: "FullPageScroll",
  props: {
    showDots: {
      type: Boolean,
      default: false,
    },
    duration: {
      type: Number,
      default: 800,
    },
    wheel: {
      type: Boolean,
      default: true,
    },
    keyboard: {
      type: Boolean,
      default: true,
    },
    // 添加滚动阈值
    wheelThreshold: {
      type: Number,
      default: 50,
    },
  },
  setup(props) {
    const currentIndex = ref(0);
    const container = ref<HTMLElement | null>(null);
    const slides = computed(() => {
      return container.value?.querySelectorAll(".fullpage-slide") || [];
    });

    // 添加滚动锁定状态
    const isScrolling = ref(false);
    let wheelDelta = 0;

    const goToSlide = (index: number) => {
      if (isScrolling.value) return;
      if (index >= 0 && index < slides.value.length) {
        isScrolling.value = true;
        currentIndex.value = index;
        setTimeout(() => {
          isScrolling.value = false;
        }, props.duration);
      }
    };

    const next = () => goToSlide(currentIndex.value + 1);
    const prev = () => goToSlide(currentIndex.value - 1);

    const handleWheel = (e: WheelEvent) => {
      if (!props.wheel || isScrolling.value) {
        e.preventDefault();
        return;
      }

      // 累积滚轮增量
      wheelDelta += e.deltaY;

      // 只有当累积的滚动量超过阈值才触发
      if (Math.abs(wheelDelta) >= props.wheelThreshold) {
        e.preventDefault();
        if (wheelDelta > 0) {
          next();
        } else {
          prev();
        }
        wheelDelta = 0; // 重置累积量
      }
    };

    const handleKeydown = (e: KeyboardEvent) => {
      if (!props.keyboard || isScrolling.value) return;

      switch (e.key) {
        case "ArrowDown":
          e.preventDefault();
          next();
          break;
        case "ArrowUp":
          e.preventDefault();
          prev();
          break;
        case "Home":
          e.preventDefault();
          goToSlide(0);
          break;
        case "End":
          e.preventDefault();
          goToSlide(slides.value.length - 1);
          break;
      }
    };

    // 触摸事件优化
    let touchStartY = 0;
    let touchEndY = 0;

    const handleTouchStart = (e: TouchEvent) => {
      touchStartY = e.touches[0].clientY;
    };

    const handleTouchMove = (e: TouchEvent) => {
      if (isScrolling.value) {
        e.preventDefault();
      }
    };

    const handleTouchEnd = (e: TouchEvent) => {
      if (isScrolling.value) return;

      touchEndY = e.changedTouches[0].clientY;
      const diff = touchStartY - touchEndY;

      if (Math.abs(diff) > 100) {
        // 提高触摸阈值
        if (diff > 0) {
          next();
        } else {
          prev();
        }
      }
    };
    watch(
      () => currentIndex.value,
      (newIndex) => {
        // console.log("newIndex", newIndex);
        const navbar = document.querySelector(".header-box");
        const logoEl = document.querySelector(".logo");
        if (!navbar) return;
        if (newIndex > 0) {
          navbar.classList.add("bg-white", "shadow-md", "text-black");
          navbar.classList.remove("text-white");
        } else {
          navbar.classList.add("text-white");
          navbar.classList.remove("bg-white", "shadow-md", "text-black");
        }
        if (navbar.classList.contains("bg-white") && logoEl) {
          logoEl.src = logo;
        } else {
          logoEl.src = logof;
        }
      }, { immediate: true }
    );
    onMounted(() => {
      if (props.wheel) {
        window.addEventListener("wheel", handleWheel, { passive: false });
      }
      if (props.keyboard) {
        window.addEventListener("keydown", handleKeydown);
      }
      window.addEventListener("touchstart", handleTouchStart, {
        passive: true,
      });
      window.addEventListener("touchmove", handleTouchMove, { passive: false });
      window.addEventListener("touchend", handleTouchEnd, { passive: true });
    });

    onUnmounted(() => {
      window.removeEventListener("wheel", handleWheel);
      window.removeEventListener("keydown", handleKeydown);
      window.removeEventListener("touchstart", handleTouchStart);
      window.removeEventListener("touchmove", handleTouchMove);
      window.removeEventListener("touchend", handleTouchEnd);
    });

    return {
      currentIndex,
      container,
      slides,
      goToSlide,
    };
  },
});
</script>

<style scoped>
.fullpage-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  touch-action: none; /* 禁用浏览器默认触摸行为 */
}
.fullpage-wrapper {
  width: 100%;
  transition: transform v-bind("`${duration}ms`") cubic-bezier(0.86, 0, 0.07, 1);
  will-change: transform; /* 优化性能 */
}

.nav-dots {
  position: fixed;
  right: 30px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
}

.dot {
  width: 12px;
  height: 12px;
  margin: 12px 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.5);
  cursor: pointer;
  transition: all 0.3s ease;
}

.dot.active {
  background: white;
  transform: scale(1.2);
}

.dot:hover {
  background: white;
}
</style>
